package org.aplikator.server.rpc;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aplikator.client.rpc.AplikatorService;
import org.aplikator.client.rpc.Command;
import org.aplikator.client.rpc.Response;
import org.aplikator.client.rpc.impl.GetApplication;
import org.aplikator.client.rpc.impl.GetFunction;
import org.aplikator.client.rpc.impl.GetPage;
import org.aplikator.client.rpc.impl.GetRecord;
import org.aplikator.client.rpc.impl.GetRecordCount;
import org.aplikator.client.rpc.impl.GetSuggestions;
import org.aplikator.client.rpc.impl.GetView;
import org.aplikator.client.rpc.impl.ProcessRecords;
import org.aplikator.client.rpc.impl.RunFunction;
import org.aplikator.server.impl.ContextImpl;
import org.aplikator.server.rpc.handler.GetApplicationHandler;
import org.aplikator.server.rpc.handler.GetFunctionHandler;
import org.aplikator.server.rpc.handler.GetPageHandler;
import org.aplikator.server.rpc.handler.GetRecordCountHandler;
import org.aplikator.server.rpc.handler.GetRecordHandler;
import org.aplikator.server.rpc.handler.GetSuggestionsHandler;
import org.aplikator.server.rpc.handler.GetViewHandler;
import org.aplikator.server.rpc.handler.ProcessRecordsHandler;
import org.aplikator.server.rpc.handler.RunFunctionHandler;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class AplikatorServiceImpl extends RemoteServiceServlet implements AplikatorService {

    private final Map<Class<? extends Command<?>>, CommandHandler<? extends Command<?>, ? extends Response>> handlers = new HashMap<Class<? extends Command<?>>, CommandHandler<? extends Command<?>, ? extends Response>>();

    {// init block - register command handlers

        handlers.put(GetApplication.class, new GetApplicationHandler());
        handlers.put(GetView.class, new GetViewHandler());
        handlers.put(ProcessRecords.class, new ProcessRecordsHandler());
        handlers.put(GetSuggestions.class, new GetSuggestionsHandler());
        handlers.put(GetRecord.class, new GetRecordHandler());
        handlers.put(GetPage.class, new GetPageHandler());
        handlers.put(GetRecordCount.class, new GetRecordCountHandler());
        handlers.put(RunFunction.class, new RunFunctionHandler());
        handlers.put(GetFunction.class, new GetFunctionHandler());
    }

    @SuppressWarnings("unchecked")
    public <T extends Response> T execute(Command<T> command) {
        CommandHandler<Command<T>, T> handler = (CommandHandler<Command<T>, T>) handlers.get(command.getClass());
        HttpServletRequest httpServletRequest = this.getThreadLocalRequest();
        HttpServletResponse httpServletResponse = this.getThreadLocalResponse();
        return handler.execute(command, new ContextImpl(httpServletRequest, httpServletResponse, this));
    }


}
